package com.desay.pangoo.itmt.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.desay.pangoo.common.lite.lang.web.BusinessException;
import com.desay.pangoo.common.lite.lang.web.PangooWebConstant;
import com.desay.pangoo.common.lite.spring.web.ControllerCommonUtils;
import com.desay.pangoo.itmt.controller.vo.TechProjectStatusVo;
import com.desay.pangoo.itmt.controller.vo.TechProjectTopicVo;
import com.desay.pangoo.itmt.entity.TechOnlineReviewFileEntity;
import com.desay.pangoo.itmt.entity.TechProjectInfoEntity;
import com.desay.pangoo.itmt.entity.TechProjectStatusEntity;
import com.desay.pangoo.itmt.entity.TechProjectTopicEntity;
import com.desay.pangoo.itmt.enums.ExceptionCodeEnum;
import com.desay.pangoo.itmt.repository.TechOnlineReviewFileRepository;
import com.desay.pangoo.itmt.repository.TechProjectInfoRepository;
import com.desay.pangoo.itmt.repository.TechProjectStatusRepository;
import com.desay.pangoo.itmt.repository.TechProjectTopicRepository;
import com.desay.pangoo.itmt.repository.spec.ExpandCriteria;
import com.desay.pangoo.itmt.repository.spec.Restrictions;
import com.desay.pangoo.itmt.service.TechProjectStatusService;

import cn.hutool.core.collection.CollUtil;

/**
 * @author uidq1163
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class TechProjectStatusServiceImpl implements TechProjectStatusService {

	@Autowired
	TechProjectTopicRepository techProjectTopicRepository;
	@Autowired
	TechProjectStatusRepository techProjectStatusRepository;
	@Autowired
	TechProjectInfoRepository techProjectInfoRepository;
	@Autowired
	TechOnlineReviewFileRepository fileRepository;

	@Override
	public Long create(TechProjectStatusVo vo) {
		String user = ControllerCommonUtils.getHeader(PangooWebConstant.HEADER_NAME_USER_FULL_NAME);
		TechProjectStatusEntity techProjectStatusEntity = new TechProjectStatusEntity();
		if (CollUtil.isNotEmpty(vo.getFileIds())) {
			Iterable<TechOnlineReviewFileEntity> allFiles = fileRepository.findAllById(vo.getFileIds());
			Set<TechOnlineReviewFileEntity> list = new HashSet<>();
			allFiles.forEach(list::add);
			techProjectStatusEntity.setFiles(list);
		} else {
			throw new BusinessException(ExceptionCodeEnum.TECHNICAL_DEFINITION_CANNOT_BE_EMPTY);
		}
		BeanUtils.copyProperties(vo, techProjectStatusEntity, ControllerCommonUtils.getNullPropertyNames(vo));
		techProjectStatusEntity.setCreator(user);
		Optional<TechProjectInfoEntity> option = techProjectInfoRepository.findById(vo.getTechProjectId());
		if (option.isPresent()) {
			techProjectStatusEntity.setTechProject(option.get());
		} else {
			throw new BusinessException(ExceptionCodeEnum.TECH_PROJECT_INFO_NOT_EXIST);
		}
		techProjectStatusRepository.save(techProjectStatusEntity);
		return techProjectStatusEntity.getId();
	}

	@Override
	public void update(Long id, TechProjectStatusVo vo) {
		String user = ControllerCommonUtils.getHeader(PangooWebConstant.HEADER_NAME_USER_FULL_NAME);
		Optional<TechProjectStatusEntity> option = techProjectStatusRepository.findById(id);
		if (option.isPresent()) {
			TechProjectStatusEntity techProjectStatusEntity = option.get();
			Set<TechOnlineReviewFileEntity> existList = techProjectStatusEntity.getFiles();
			if (CollUtil.isNotEmpty(vo.getFileIds())) {
				Iterable<TechOnlineReviewFileEntity> allFiles = fileRepository.findAllById(vo.getFileIds());
				allFiles.forEach(existList::add);
			}
			techProjectStatusEntity.setFiles(existList);
			BeanUtils.copyProperties(vo, techProjectStatusEntity, ControllerCommonUtils.getNullPropertyNames(vo));
			techProjectStatusEntity.setUpdator(user);
			techProjectStatusRepository.save(techProjectStatusEntity);
		}
	}

	@Override
	public Long createTopic(TechProjectTopicVo vo) {
		String user = ControllerCommonUtils.getHeader(PangooWebConstant.HEADER_NAME_USER_FULL_NAME);
		TechProjectTopicEntity techProjectTopicEntity = new TechProjectTopicEntity();
		techProjectTopicEntity.setCreator(user);
		// 关联课题
		Optional<TechProjectInfoEntity> option = techProjectInfoRepository.findById(vo.getTechProjectId());
		if (option.isPresent()) {
			techProjectTopicEntity.setTechProject(option.get());
		} else {
			throw new BusinessException(ExceptionCodeEnum.TECH_PROJECT_INFO_NOT_EXIST);
		}
		// 关联课题状态变更申请
		Optional<TechProjectStatusEntity> optionStatus = techProjectStatusRepository
				.findById(vo.getTechProjectStatusId());
		TechProjectStatusEntity entity = null;
		if (optionStatus.isPresent()) {
			entity = optionStatus.get();
			techProjectTopicEntity.setTechProjectStatus(entity);
			entity.setTechProjectTopic(techProjectTopicEntity);
		} else {
			throw new BusinessException(ExceptionCodeEnum.TECH_PROJECT_INFO_NOT_EXIST);
		}
		BeanUtils.copyProperties(vo, techProjectTopicEntity, ControllerCommonUtils.getNullPropertyNames(vo));
		techProjectTopicRepository.save(techProjectTopicEntity);
		techProjectStatusRepository.save(entity);
		return techProjectTopicEntity.getId();
	}

	@Override
	public void updateTopic(Long id, TechProjectTopicVo vo) {
		String user = ControllerCommonUtils.getHeader(PangooWebConstant.HEADER_NAME_USER_FULL_NAME);
		// 关联课题
		Optional<TechProjectTopicEntity> option = techProjectTopicRepository.findById(id);
		if (option.isPresent()) {
			TechProjectTopicEntity entity = option.get();
			entity.setUpdator(user);
			BeanUtils.copyProperties(vo, entity, ControllerCommonUtils.getNullPropertyNames(vo));
			techProjectTopicRepository.save(entity);
		} else {
			throw new BusinessException(ExceptionCodeEnum.TECH_PROJECT_INFO_NOT_EXIST);
		}

	}

	@Override
	public Page<TechProjectStatusEntity> getList(Integer pageSize, Integer pageNum, Integer auditStatus,
			Integer taskStatus, Integer approvalStatus, String creator) {
		ExpandCriteria<TechProjectStatusEntity> c = new ExpandCriteria<>();
		c.add(Restrictions.eq("taskStatus", taskStatus, true));
		c.add(Restrictions.eq("approvalStatus", approvalStatus, true));
		c.add(Restrictions.eq("auditStatus", auditStatus, true));
		c.add(Restrictions.like("creator", creator, true));
		List<Order> orders = new ArrayList<>();
		Order order = new Order(Sort.Direction.DESC, "createTime");
		orders.add(order);
		Pageable pageReq = PageRequest.of(pageNum - 1, pageSize, Sort.by(orders));
		return techProjectStatusRepository.findAll(c, pageReq);
	}

	@Override
	public List<TechProjectTopicEntity> getAllTopicList() {
		Specification<TechProjectTopicEntity> c = new ExpandCriteria<>();
		return techProjectTopicRepository.findAll(c);
	}

	@Override
	public void audit(Long id, TechProjectStatusVo vo) {
		String user = ControllerCommonUtils.getHeader(PangooWebConstant.HEADER_NAME_USER_FULL_NAME);
		Optional<TechProjectStatusEntity> option = techProjectStatusRepository.findById(id);
		if (option.isPresent()) {
			TechProjectStatusEntity statusEntity = option.get();
			statusEntity.setAuditStatus(vo.getAuditStatus());
			statusEntity.setAuditComments(vo.getAuditComments());
			statusEntity.setAuditTime(new Date());
			statusEntity.setAuditor(user);
			techProjectStatusRepository.save(statusEntity);
		}
	}

	@Override
	public void task(Long id, TechProjectStatusVo vo) {
		String user = ControllerCommonUtils.getHeader(PangooWebConstant.HEADER_NAME_USER_FULL_NAME);
		Optional<TechProjectStatusEntity> option = techProjectStatusRepository.findById(id);
		if (option.isPresent()) {
			TechProjectStatusEntity statusEntity = option.get();
			statusEntity.setTaskStatus(vo.getTaskStatus());
			statusEntity.setTaskComments(vo.getTaskComments());
			statusEntity.setTaskAuditTime(new Date());
			statusEntity.setTaskAuditor(user);
			techProjectStatusRepository.save(statusEntity);
		}
	}

	@Override
	public void approval(Long id, TechProjectStatusVo vo) {
		String user = ControllerCommonUtils.getHeader(PangooWebConstant.HEADER_NAME_USER_FULL_NAME);
		Optional<TechProjectStatusEntity> option = techProjectStatusRepository.findById(id);
		if (option.isPresent()) {
			TechProjectStatusEntity statusEntity = option.get();
			statusEntity.setApprovalStatus(vo.getApprovalStatus());
			statusEntity.setApprovalComments(vo.getAuditComments());
			statusEntity.setApprovalTime(new Date());
			statusEntity.setApprovalor(user);
			techProjectStatusRepository.save(statusEntity);
		}
	}

	@Override
	public TechProjectStatusEntity getInfoById(Long id) {
		Optional<TechProjectStatusEntity> option = techProjectStatusRepository.findById(id);
		if (option.isPresent()) {
			return option.get();
		}
		return null;
	}
}
